home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Visual Basic Source Code
/
Visual Basic Source Code.iso
/
vbsource
/
256pb2
/
dib.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-03-12
|
14KB
|
428 lines
//-----------------------------------------------------------------------------
// DIB.C
//
// This is a collection of useful DIB manipulation/information gathering
// functions. Many functions are supplied simply to take the burden
// of taking into account whether a DIB is a Win30 style or OS/2 style
// DIB away from the application.
//
// The functions in this module assume that the DIB pointers or handles
// passed to them point to a block of memory in one of two formats:
//
// a) BITMAPINFOHEADER + color table + DIB bits (3.0 style DIB)
// b) BITMAPCOREHEADER + color table + DIB bits (OS/2 PM style)
//
// The SDK Reference, Volume 2 describes these data structures.
//
// A number of functions in this module were lifted from SHOWDIB,
// and modified to handle OS/2 DIBs.
//
// The functions in this module could be streamlined (made faster and
// smaller) by removing the OS/2 DIB specific code, and assuming all
// DIBs passed to it are Win30 style DIBs. The DIB file reading code
// would need to be modified to always convert DIBs to Win30 style
// DIBs. The only reason this isn't done in DIBView is because DIBView
// was written to test display and printer drivers (which are supposed
// to support OS/2 DIBs wherever they support Win30 style DIBs). SHOWDIB
// is a great example of how to go about doing this.
//-----------------------------------------------------------------------------
#include <windows.h>
#include <memory.h>
#include "errors.h"
#include "dib.h"
//---------------------------------------------------------------------
//
// Function: FindDIBBits
//
// Purpose: Given a pointer to a DIB, returns a pointer to the
// DIB's bitmap bits.
//
// Parms: lpbi == pointer to DIB header (either BITMAPINFOHEADER
// or BITMAPCOREHEADER)
//
// History: Date Reason
// 6/01/91 Created
//
//---------------------------------------------------------------------
LPSTR FAR PASCAL FindDIBBits (LPSTR lpbi)
{
return (lpbi + *(LPDWORD)lpbi + PaletteSize (lpbi));
}
//---------------------------------------------------------------------
//
// Function: DIBNumColors
//
// Purpose: Given a pointer to a DIB, returns a number of colors in
// the DIB's color table.
//
// Parms: lpbi == pointer to DIB header (either BITMAPINFOHEADER
// or BITMAPCOREHEADER)
//
// History: Date Reason
// 6/01/91 Created
//
//---------------------------------------------------------------------
WORD FAR PASCAL DIBNumColors (LPSTR lpbi)
{
WORD wBitCount;
// If this is a Windows style DIB, the number of colors in the
// color table can be less than the number of bits per pixel
// allows for (i.e. lpbi->biClrUsed can be set to some value).
// If this is the case, return the appropriate value.
if (IS_WIN30_DIB (lpbi))
{
DWORD dwClrUsed;
dwClrUsed = ((LPBITMAPINFOHEADER) lpbi)->biClrUsed;
if (dwClrUsed)
return (WORD) dwClrUsed;
}
// Calculate the number of colors in the color table based on
// the number of bits per pixel for the DIB.
if (IS_WIN30_DIB (lpbi))
wBitCount = ((LPBITMAPINFOHEADER) lpbi)->biBitCount;
else
wBitCount = ((LPBITMAPCOREHEADER) lpbi)->bcBitCount;
switch (wBitCount)
{
case 1:
return 2;
case 4:
return 16;
case 8:
return 256;
default:
return 0;
}
}
//---------------------------------------------------------------------
//
// Function: PaletteSize
//
// Purpose: Given a pointer to a DIB, returns number of bytes
// in the DIB's color table.
//
// Parms: lpbi == pointer to DIB header (either BITMAPINFOHEADER
// or BITMAPCOREHEADER)
//
// History: Date Reason
// 6/01/91 Created
//
//---------------------------------------------------------------------
WORD FAR PASCAL PaletteSize (LPSTR lpbi)
{
if (IS_WIN30_DIB (lpbi))
return (DIBNumColors (lpbi) * sizeof (RGBQUAD));
else
return (DIBNumColors (lpbi) * sizeof (RGBTRIPLE));
}
//---------------------------------------------------------------------
//
// Function: CreateDIBPalette
//
// Purpose: Given a handle to a DIB, constructs a logical palette,
// and returns a handle to this palette.
//
// Stolen almost verbatim from ShowDIB.
//
// Parms: hDIB == HANDLE to global memory with a DIB header
// (either BITMAPINFOHEADER or BITMAPCOREHEADER)
//
// History: Date Reason
// 6/01/91 Created
//
//---------------------------------------------------------------------
HPALETTE FAR PASCAL CreateDIBPalette (HANDLE hDIB)
{
LPLOGPALETTE lpPal;
HANDLE hLogPal;
HPALETTE hPal = NULL;
int i, wNumColors;
LPSTR lpbi;
LPBITMAPINFO lpbmi;
LPBITMAPCOREINFO lpbmc;
BOOL bWinStyleDIB;
if (!hDIB)
return NULL;
lpbi = GlobalLock (hDIB);
lpbmi = (LPBITMAPINFO) lpbi;
lpbmc = (LPBITMAPCOREINFO) lpbi;
wNumColors = DIBNumColors (lpbi);
bWinStyleDIB = IS_WIN30_DIB (lpbi);
if (wNumColors)
{
hLogPal = GlobalAlloc (GHND, sizeof (LOGPALETTE) +
sizeof (PALETTEENTRY) * wNumColors);
if (!hLogPal)
{
DIBError (ERR_CREATEPAL);
GlobalUnlock (hDIB);
return NULL;
}
lpPal = (LPLOGPALETTE) GlobalLock (hLogPal);
lpPal->palVersion = PALVERSION;
lpPal->palNumEntries = wNumColors;
for (i = 0; i < wNumColors; i++)
{
if (bWinStyleDIB)
{
lpPal->palPalEntry[i].peRed = lpbmi->bmiColors[i].rgbRed;
lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen;
lpPal->palPalEntry[i].peBlue = lpbmi->bmiColors[i].rgbBlue;
lpPal->palPalEntry[i].peFlags = 0;
}
else
{
lpPal->palPalEntry[i].peRed = lpbmc->bmciColors[i].rgbtRed;
lpPal->palPalEntry[i].peGreen = lpbmc->bmciColors[i].rgbtGreen;
lpPal->palPalEntry[i].peBlue = lpbmc->bmciColors[i].rgbtBlue;
lpPal->palPalEntry[i].peFlags = 0;
}
}
hPal = CreatePalette (lpPal);
if (!hPal)
DIBError (ERR_CREATEPAL);
GlobalUnlock (hLogPal);
GlobalFree (hLogPal);
}
GlobalUnlock (hDIB);
return hPal;
}
//---------------------------------------------------------------------
//
// Function: DIBHeight
//
// Purpose: Given a pointer to a DIB, returns its height. Note
// that it returns a DWORD (since a Win30 DIB can have
// a DWORD in its height field), but under Win30, the
// high order word isn't used!
//
// Parms: lpDIB == pointer to DIB header (either BITMAPINFOHEADER
// or BITMAPCOREHEADER)
//
// History: Date Reason
// 6/01/91 Created
//
//---------------------------------------------------------------------
DWORD FAR PASCAL DIBHeight (LPSTR lpDIB)
{
LPBITMAPINFOHEADER lpbmi;
LPBITMAPCOREHEADER lpbmc;
lpbmi = (LPBITMAPINFOHEADER) lpDIB;
lpbmc = (LPBITMAPCOREHEADER) lpDIB;
if (lpbmi->biSize == sizeof (BITMAPINFOHEADER))
return lpbmi->biHeight;
else
return (DWORD) lpbmc->bcHeight;
}
//---------------------------------------------------------------------
//
// Function: DIBWidth
//
// Purpose: Given a pointer to a DIB, returns its width. Note
// that it returns a DWORD (since a Win30 DIB can have
// a DWORD in its width field), but under Win30, the
// high order word isn't used!
//
// Parms: lpDIB == pointer to DIB header (either BITMAPINFOHE